package cn.colins.raft.rpc.handler.chanel;


import cn.colins.raft.enity.HeartBeatResult;
import cn.colins.raft.config.ServerConfig;
import cn.colins.raft.rpc.RpcRemoteContext;
import cn.colins.raft.rpc.future.RpcWriteFuture;
import cn.colins.raft.rpc.session.RpcSessionFactory;
import cn.colins.raft.utils.ThreadPoolUtils;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.ReferenceCountUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @Description  心跳请求返回值处理
 * @Author czl
 * @Version V1.0.0
 * @Since 1.0
 * @Date 2023/6/12
 */
public class HeartBeatResultHandler extends SimpleChannelInboundHandler<HeartBeatResult> {
    private static final Logger log = LoggerFactory.getLogger(HeartBeatResultHandler.class);


    @Override
    protected void channelRead0(ChannelHandlerContext context, HeartBeatResult rpcResponse) throws Exception {
        // 获取返回值后 同步响应请求
        ThreadPoolUtils.nettyClientAsyncPool.execute(()->{
            try{
                RpcWriteFuture requestCache = RpcRemoteContext.getRequestCache(rpcResponse.getRequestId());
                if(requestCache!=null){
                    requestCache.setResponse(rpcResponse);
                }
            }finally {
                //释放
                ReferenceCountUtil.release(rpcResponse);
            }
        });
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        log.error("[{}] 发生异常下线：{}",ctx.channel().remoteAddress(),cause.getMessage(),cause);
        // 需要移除通信管道
        String address = ctx.channel().remoteAddress().toString().replace("/", "");
        String[] split = address.split(":");
        // follow或者candidate 宕机了
        // 资源清理/释放
        RpcSessionFactory.channelClear(new ServerConfig(split[0],Integer.valueOf(split[1])));
    }
}
